import { Map } from "ol";
import type { MapEventHandler, MapOptions } from "ol/Map";
import { createGaodeBaseLayer } from "./createLayer";
import { createBaseView } from "./createView";
import { createBaseControls } from "./createControls";
import { CreatePointOptions, createPointLayer } from "../draw/drawPoints";

import { CreateLineOptions, createLineLayer } from "../draw/drawLines";

import { EventsKey } from "ol/events";
import { CreateOverlayOptions, createOverlay } from "../draw/drawOverlay";
import { CreateHeatmapOptions, createHeatmapLayer } from "../draw/drawHeatmap";
import { AreaData, CreateAreaOptions, createAreaLayer } from "../draw/drawArea";

class AMap extends Map {
  constructor(parameters: MapOptions) {
    super(parameters);
  }
  drawPoints<T>(data: T[], options?: CreatePointOptions) {
    const map = this;
    const layer = createPointLayer(data, options);
    map.addLayer(layer);
  }
  drawOverlay<T>(data: T[], options?: CreateOverlayOptions<T>) {
    const map = this;
    const overlays = createOverlay(data, options);
    if (overlays.length) {
      overlays.forEach((overlay) => {
        map.addOverlay(overlay);
      });
    }
  }
  drawLines<T>(data: T[], options?: CreateLineOptions) {
    const map = this;
    const layer = createLineLayer(data, options);
    map.addLayer(layer);
  }
  drawHeatmap<T>(data: T[], options?: CreateHeatmapOptions) {
    const map = this;
    const layer = createHeatmapLayer(data, options);
    map.addLayer(layer);
  }
  drawArea<T extends AreaData>(data: T[], options?: CreateAreaOptions) {
    const map = this;
    const layers = createAreaLayer(data, options);
    if (layers.length) {
      layers.forEach((layer) => map.addLayer(layer));
    }
  }
}

export function createMap(options: MapOptions) {
  if (!options.layers) {
    options.layers = [createGaodeBaseLayer()];
  }

  if (!options.view) {
    options.view = createBaseView();
  }

  if (!options.controls) {
    options.controls = createBaseControls();
  }

  const map = new AMap(options);

  return map;
}
